package com.djf.djfpgsql.wrapper.comparison;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.djf.djfpgsql.entity.User;
import com.djf.djfpgsql.wrapper.mapper.UserWrapperMapper;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

/**
 * Lambda表达式Wrapper示例 - 纯Wrapper方式的最高级形式
 * 展示最类型安全、最优雅的MyBatis-Plus使用方式
 */
@Service
public class LambdaWrapperService extends ServiceImpl<UserWrapperMapper, User> {

    // ==================== Lambda Wrapper的终极优势 ====================
    
    /**
     * Lambda方式：完全类型安全的条件查询
     * 优势：
     * 1. 编译时字段检查，重构安全
     * 2. IDE智能提示和自动补全
     * 3. 完全避免字段名拼写错误
     * 4. 代码可读性最高
     */
    public List<User> getUsersByConditionsLambda(String name, Integer minAge, Boolean isActive) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        
        // 使用方法引用，编译时检查字段存在性
        wrapper.like(User::getName, name)           // 如果getName方法不存在，编译报错
               .ge(User::getAge, minAge)            // 类型自动推断，age必须是Integer
               .eq(User::getIsActive, isActive)     // 布尔值自动处理
               .orderByDesc(User::getCreatedAt);    // 时间字段自动识别
        
        return list(wrapper);
    }
    
    /**
     * 对比：字符串方式 vs Lambda方式
     */
    public void comparisonExample() {
        // ❌ 字符串方式：容易出错
        LambdaQueryWrapper<User> stringWrapper = new LambdaQueryWrapper<>();
        // stringWrapper.eq("nam", "张三");  // 字段名拼写错误，运行时才发现
        
        // ✅ Lambda方式：编译时检查
        LambdaQueryWrapper<User> lambdaWrapper = new LambdaQueryWrapper<>();
        lambdaWrapper.eq(User::getName, "张三");  // 如果字段不存在，编译就报错
    }
    
    /**
     * Lambda方式：复杂条件组合
     * 特点：代码读起来像自然语言
     */
    public List<User> getComplexConditionsLambda(String keyword, Integer minAge, Double minBalance) {
        return list(
            new LambdaQueryWrapper<User>()
                .and(wrapper -> wrapper
                    .like(User::getName, keyword)       // 姓名包含关键词
                    .or()
                    .like(User::getEmail, keyword)      // 或邮箱包含关键词
                )
                .ge(User::getAge, minAge)               // 且年龄大于等于最小值
                .ge(User::getBalance, minBalance)       // 且余额大于等于最小值
                .orderByDesc(User::getBalance)          // 按余额降序
                .orderByDesc(User::getCreatedAt)        // 再按创建时间降序
        );
    }
    
    /**
     * Lambda方式：动态条件构建
     * 特点：条件表达式清晰，逻辑一目了然
     */
    public List<User> getDynamicConditionsLambda(
            String name, String email, Integer minAge, Integer maxAge, 
            Double minBalance, Boolean isActive, LocalDateTime startDate) {
        
        return list(
            new LambdaQueryWrapper<User>()
                .like(name != null && !name.isEmpty(), User::getName, name)
                .like(email != null && !email.isEmpty(), User::getEmail, email)
                .ge(minAge != null, User::getAge, minAge)
                .le(maxAge != null, User::getAge, maxAge)
                .ge(minBalance != null, User::getBalance, minBalance)
                .eq(isActive != null, User::getIsActive, isActive)
                .ge(startDate != null, User::getCreatedAt, startDate)
                .orderByDesc(User::getCreatedAt)
        );
    }
    
    /**
     * Lambda方式：类型安全的更新操作
     * 特点：字段和值的类型完全匹配
     */
    public boolean updateUserStatusLambda(List<Long> userIds, Boolean newStatus, String updatedBy) {
        LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
        
        wrapper.in(User::getId, userIds)                        // WHERE id IN (...)
               .set(User::getIsActive, newStatus)               // SET is_active = ?
               .set(User::getUpdatedAt, LocalDateTime.now())    // SET updated_at = ?
               .set(User::getUpdatedBy, updatedBy);             // SET updated_by = ?
        
        return update(wrapper);
    }
    
    /**
     * Lambda方式：优雅的分页查询
     * 特点：排序字段类型安全
     */
    public List<User> getPagedUsersLambda(int page, int size, boolean sortByBalance) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        
        if (sortByBalance) {
            wrapper.orderByDesc(User::getBalance)      // 按余额降序
                   .orderByDesc(User::getCreatedAt);   // 再按创建时间降序
        } else {
            wrapper.orderByDesc(User::getCreatedAt)    // 按创建时间降序
                   .orderByDesc(User::getBalance);     // 再按余额降序
        }
        
        int offset = (page - 1) * size;
        wrapper.last("LIMIT " + size + " OFFSET " + offset);
        
        return list(wrapper);
    }
    
    /**
     * Lambda方式：统计查询
     * 特点：聚合字段类型明确
     */
    public long countActiveUsersLambda(Integer minAge, Double minBalance) {
        return count(
            new LambdaQueryWrapper<User>()
                .eq(User::getIsActive, true)            // 活跃用户
                .ge(minAge != null, User::getAge, minAge)           // 年龄条件
                .ge(minBalance != null, User::getBalance, minBalance) // 余额条件
        );
    }
    
    /**
     * Lambda方式：条件构造器复用
     * 特点：可以抽取公共条件逻辑
     */
    public LambdaQueryWrapper<User> buildActiveUserConditions(String keyword) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        
        wrapper.eq(User::getIsActive, true);  // 基础条件：活跃用户
        
        if (keyword != null && !keyword.isEmpty()) {
            wrapper.and(w -> w
                .like(User::getName, keyword)
                .or()
                .like(User::getEmail, keyword)
            );
        }
        
        return wrapper;
    }
    
    // 复用条件构造逻辑的示例
    public List<User> searchActiveUsers(String keyword) {
        return list(
            buildActiveUserConditions(keyword)
                .orderByDesc(User::getCreatedAt)
        );
    }
    
    public long countActiveUsers(String keyword) {
        return count(buildActiveUserConditions(keyword));
    }
    
    public List<User> getTopActiveUsers(String keyword, int limit) {
        return list(
            buildActiveUserConditions(keyword)
                .orderByDesc(User::getBalance)
                .last("LIMIT " + limit)
        );
    }
    
    /**
     * Lambda方式：链式调用的极致优雅
     * 特点：代码读起来像业务需求描述
     */
    public List<User> getVipUsersLambda() {
        return list(
            new LambdaQueryWrapper<User>()
                .eq(User::getIsActive, true)        // 活跃用户
                .ge(User::getAge, 18)               // 成年人
                .ge(User::getBalance, 10000.0)      // 余额1万以上
                .isNotNull(User::getEmail)          // 有邮箱
                .ne(User::getEmail, "")             // 邮箱不为空
                .orderByDesc(User::getBalance)      // 按余额降序
                .orderByAsc(User::getAge)           // 再按年龄升序
        );
    }
    
    /**
     * Lambda方式：时间范围查询
     * 特点：时间字段类型安全
     */
    public List<User> getUsersByDateRangeLambda(LocalDateTime startDate, LocalDateTime endDate) {
        return list(
            new LambdaQueryWrapper<User>()
                .ge(startDate != null, User::getCreatedAt, startDate)  // 开始时间
                .le(endDate != null, User::getCreatedAt, endDate)      // 结束时间
                .orderByDesc(User::getCreatedAt)
        );
    }
    
    /**
     * Lambda方式：批量条件查询
     * 特点：IN查询类型安全
     */
    public List<User> getUsersByIdsLambda(List<Long> userIds) {
        if (userIds == null || userIds.isEmpty()) {
            return List.of();
        }
        
        return list(
            new LambdaQueryWrapper<User>()
                .in(User::getId, userIds)           // ID在列表中
                .eq(User::getIsActive, true)        // 且为活跃用户
                .orderByDesc(User::getCreatedAt)
        );
    }
    
    /**
     * Lambda方式：NOT条件查询
     * 特点：否定条件清晰表达
     */
    public List<User> getSpecialUsersLambda() {
        return list(
            new LambdaQueryWrapper<User>()
                .ne(User::getIsActive, false)       // 不是非活跃用户（即活跃用户）
                .isNotNull(User::getEmail)          // 邮箱不为空
                .notLike(User::getEmail, "test")    // 邮箱不包含test
                .orderByDesc(User::getCreatedAt)
        );
    }
}

/*
 * Lambda Wrapper的核心优势总结：
 * 
 * 1. 编译时安全：
 *    - 字段名错误在编译时就能发现
 *    - 类型不匹配编译时报错
 *    - 重构时自动更新字段引用
 * 
 * 2. IDE支持：
 *    - 智能提示和自动补全
 *    - 快速导航到字段定义
 *    - 重构工具完全支持
 * 
 * 3. 代码可读性：
 *    - 方法引用比字符串更直观
 *    - 链式调用逻辑清晰
 *    - 代码自文档化
 * 
 * 4. 维护性：
 *    - 字段重命名自动更新
 *    - 删除字段编译时发现
 *    - 类型变更自动检查
 * 
 * 5. 性能：
 *    - 与字符串方式性能相同
 *    - 编译时优化更好
 * 
 * 使用建议：
 * - 新项目优先使用Lambda方式
 * - 老项目逐步迁移到Lambda方式
 * - 复杂查询可以混合使用
 * - 团队统一使用Lambda规范
 */